/*
@file: libCommon.cpp
@author: ZZH
@date: 2023-02-03
@info: 动态库公共部分
*/
#include <cmath>
#include <cstddef>
#include <cstring>
#include "libCommon.h"

void normalize(BasicType* output, BasicType* buf, size_t len)
{
    if (nullptr == buf || 0 == len)
        return;

    BasicType sum = 0;

    for (size_t i = 0; i < len; i++) sum += buf[i];

    if (0 != sum) {
        for (size_t i = 0; i < len; i++) output[i] = buf[i] / sum;
    }
}

void swap_arr(BasicType* output, BasicType* buf, size_t len)
{
    if (nullptr == buf || nullptr == output || 0 == len)
        return;

    unsigned half_len = len / 2;

    for (size_t i = 0; i < half_len; i++) {
        BasicType tmp = buf[i];
        output[i] = buf[half_len + i];
        output[half_len + i] = tmp;
    }
}

void hamming(BasicType* buf, size_t len)
{
    if (nullptr == buf || len < 2)
        return;

    const BasicType arg = M_PI * 2 / (len - 1);

    for (size_t i = 0; i < len; i++) buf[i] = 0.54 - 0.46 * cos(i * arg);
}

// 完整卷积, 会计算卷积核超出数据的部分
void full_conv(BasicType* output, BasicType* arr1, size_t len1, BasicType* arr2, size_t len2)
{
    if (len1 == 0 || len2 == 0)
        return;

    if (nullptr == output || nullptr == arr1 || nullptr == arr2)
        return;

    const size_t outSize = len1 + len2 - 1;

    BasicType *longArr = nullptr, *shortArr = nullptr;
    size_t longLen = 0, shortLen = 0;

    if (len1 > len2) {
        longArr = arr1;
        longLen = len1;
        shortArr = arr2;
        shortLen = len2;
    } else {
        longArr = arr2;
        longLen = len2;
        shortArr = arr1;
        shortLen = len1;
    }

    size_t count = 0;

    for (size_t t = 0; t < outSize; t++) // 总的计算次数
    {
        BasicType res = 0;
        size_t i1 = 0, i2 = 0;

        if (t < shortLen) {
            i1 = 0;
            i2 = t;
        } else {
            i2 = shortLen - 1;
            i1 = t - i2;
        }

        if (t < shortLen)
            count++;
        else if (t >= longLen)
            count--;

        for (size_t j = 0; j < count; j++, i1++, i2--) res += longArr[i1] * shortArr[i2];

        output[t] = res;
    }
}

// 有效卷积, 仅计算双方完全重合时的部分
void valid_conv(BasicType* output, BasicType* arr1, size_t len1, BasicType* arr2, size_t len2)
{
    if (len1 == 0 || len2 == 0)
        return;

    if (nullptr == output || nullptr == arr1 || nullptr == arr2)
        return;

    const size_t outSize = len1 - len2 + 1;

    BasicType *longArr = nullptr, *shortArr = nullptr;
    size_t shortLen = 0;

    if (len1 > len2) {
        longArr = arr1;
        shortArr = arr2;
        shortLen = len2;
    } else {
        longArr = arr2;
        shortArr = arr1;
        shortLen = len1;
    }

    for (size_t t = 0; t < outSize; t++) // 总的计算次数
    {
        size_t i1 = t;            // 第一个数组的取数起始下标
        size_t i2 = shortLen - 1; // 第二个数组的取数起始下标
        BasicType res = 0;

        for (size_t j = 0; j < shortLen; j++, i1++, i2--) res += longArr[i1] * shortArr[i2];

        output[t] = res;
    }
}
